/* See the files LICENSE and COPYRIGHT for license and copyright information */
package org.rubiq.reader;

import java.io.IOException;
import java.io.PushbackReader;
import java.io.Reader;

import org.rubiq.LispExpression;

/**
 * @author <a href="mailto:ola.bini@gmail.com">Ola Bini</a>
 */
public class DefaultReader {
    private PushbackReader reader;

    private ReaderMacro[] readMacros;

    public DefaultReader(Reader reader) {
        this.reader = new PushbackReader(reader);
        this.readMacros = new ReaderMacro[128];
        ReaderMacro.initDefaultMacros(this.readMacros);
    }
    
    public LispExpression readNext(LispExpression parent) throws IOException {
        int tag;
        while((tag = reader.read()) != -1 && Character.isWhitespace(tag));
        if(tag == -1) {
            if(parent != null) {
                throw new RuntimeException("Unexpected end of list [inside " + parent + "]");
            }
           return null;
        }

        ReaderMacro rm = getReaderMacroFor(tag);
        return rm.read(this, reader, tag, parent);
    }

    public LispExpression readNext() throws IOException {
        return readNext(null);
    }

    protected ReaderMacro getReaderMacroFor(int tag) {
        if(tag >= 0 && tag < readMacros.length && readMacros[tag] != null) {
            return readMacros[tag];
        } else {
            return ReaderMacro.SCALAR;
        }
    }

    public static void main(String[] args) throws Exception {
        java.io.FileReader ff = new java.io.FileReader(args[0]);
        DefaultReader def = new DefaultReader(ff);
        LispExpression val;
        while((val = def.readNext()) != null) {
            System.err.println(": " + val);
        }
        ff.close();
    }
}// DefaultReader
